package org.example;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;

public class App {

        public static void main(String[] args) throws LifecycleException {
        Tomcat tomcat = new Tomcat();
        tomcat.setBaseDir("temp");
        tomcat.setPort(8080);

        String contextPath = "/";
        String docBase = new File(".").getAbsolutePath();

        Context context = tomcat.addContext(contextPath, docBase);
        HttpServlet servlet = new HttpServlet() {


            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
                PrintWriter writer = resp.getWriter();
                // syncDeal(writer);
                asyncDealWithNoComplete(req, writer);

            }

            private void asyncDeal2(HttpServletRequest req, PrintWriter writer) {
                AsyncContext asyncContext = req.startAsync();
                System.out.println(Thread.currentThread().getName()); // http-nio-8080-exec-1
                ExecutorService executorService = Executors.newCachedThreadPool();
                executorService.submit(() -> {
                    System.out.println(Thread.currentThread().getName()); // pool-1-thread-1
                    writer.println("<html><title>Welcome</title><body>");
                    writer.println("<h1>Have a Great Day!</h1>");
                    writer.println("</body></html>");
                    asyncContext.complete();
                });
            }

            /**
             * 将一直等待直到超时
             * @param req
             * @param writer
             */
            private void asyncDealWithNoComplete(HttpServletRequest req, PrintWriter writer) {
                AsyncContext asyncContext = req.startAsync();
                System.out.println(Thread.currentThread().getName()); // http-nio-8080-exec-1
                ExecutorService executorService = Executors.newCachedThreadPool();
                executorService.submit(() -> {
                    System.out.println(Thread.currentThread().getName()); // pool-1-thread-1
                    writer.println("<html><title>Welcome</title><body>");
                    writer.println("<h1>Have a Great Day!</h1>");
                    writer.println("</body></html>");
                    // asyncContext.complete();
                });
                asyncContext.addListener(new AsyncListener() {
                    @Override
                    public void onComplete(AsyncEvent event) throws IOException {

                    }

                    @Override
                    public void onTimeout(AsyncEvent event) throws IOException {
                        System.out.println("timeout");
                    }

                    @Override
                    public void onError(AsyncEvent event) throws IOException {
                        System.out.println("error");
                    }

                    @Override
                    public void onStartAsync(AsyncEvent event) throws IOException {

                    }
                });
            }


            /**
             * http-nio-8080-exec-1
             * http-nio-8080-exec-2
             * @param req
             * @param writer
             */
            private void asyncDeal(HttpServletRequest req, PrintWriter writer) {
                AsyncContext asyncContext = req.startAsync();
                System.out.println(Thread.currentThread().getName()); // http-nio-8080-exec-1
                asyncContext.start(() -> {
                    System.out.println(Thread.currentThread().getName()); // http-nio-8080-exec-2
                    writer.println("<html><title>Welcome</title><body>");
                    writer.println("<h1>Have a Great Day!</h1>");
                    writer.println("</body></html>");
                    asyncContext.complete();
                });
            }

            private void syncDeal(PrintWriter writer) {
                System.out.println(Thread.currentThread().getName());  // http-nio-8080-exec-1
                writer.println("<html><title>Welcome</title><body>");
                writer.println("<h1>Have a Great Day!</h1>");
                writer.println("</body></html>");
            }

            /**
             * 无法正常返回 因为请求开启异步
             * @param writer
             */
            private void asyncDealError(PrintWriter writer) {
                ExecutorService executorService = Executors.newCachedThreadPool();
                executorService.submit(() -> {
                    System.out.println(Thread.currentThread().getName());  // http-nio-8080-exec-1
                    writer.println("<html><title>Welcome</title><body>");
                    writer.println("<h1>Have a Great Day!</h1>");
                    writer.println("</body></html>");
                });
            }
        };

        String servletName = "Servlet1";
        String urlPattern = "/go";

        Wrapper wrapper = tomcat.addServlet(contextPath, servletName, servlet);
        wrapper.setAsyncSupported(true);
        context.addServletMappingDecoded(urlPattern, servletName);

        tomcat.start();
        tomcat.getServer().await();
    }
}